﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 第三次作业
{
    class Program
    {
        static void Main(string[] args)
        {
            for (int i = 0; i < 10; i++)
            {
                Random rd = new Random(int.Parse(DateTime.Now.ToString("HHmmssfff")) + i);
                                                                        //使用这行代码是因为在测试中发现如果直接多次生成随机数都会是重复的！
                CreateShape(rd);                             //多次调用创建十个随机图形
            }
            Console.WriteLine("总面积是：" + Shape.sum.ToString());
            Console.ReadKey();
        }

        /*随机创建形状对象的方法*/
         static public Shape CreateShape(Random rd)
        {
            Shape sp=null;
            int kind;
            kind = rd.Next(0, 4);
            if (kind == 0)
            {
                sp = new Circle(10 * rd.NextDouble());
            }
            else if (kind == 1)
            {
                sp = new Rectangle(10 * rd.NextDouble(), 10 * rd.NextDouble());
            }
            else if (kind == 2)
            {
                sp = new Square(10 * rd.NextDouble());
            }
            else
            {
                bool tag = false;
                while (tag == false)                         //要确保创建的三角形是合法的，如果这个随即边长不合法就要重新创建
                {
                    sp = new Triangle(10 * rd.NextDouble(), 10 * rd.NextDouble(), 10 * rd.NextDouble());
                    if (sp.IsLegal() == true)
                    {
                        tag = true;
                    }
                    else
                    {
                        Console.WriteLine("\t创建三角形不合法,重新创建!");
                    }
                }
            }
            return sp;
        }
    }

    /*定义抽象类：形状*/
    public abstract class Shape
    {
        public static double sum;
        public abstract double GetArea();           //求面积
        public abstract bool IsLegal();                 //判断是否合法
    }

    /*定义圆形类*/
    public class Circle : Shape
    {
        private double _r;                                  //半径
        public double R                                     //半径属性
        {
            get { return _r; }
            set { _r = value; }
        }
        public Circle(double r)                            //构造函数要完成三个任务：输出创建了什么、赋值给半径、计算面积并累加
        {
            Console.Write("创建的图形是：圆形！");
            this.R = r;
            Console.WriteLine("\t面积是：" + this.GetArea().ToString());
            Shape.sum += this.GetArea();
        }
        public override double GetArea()           //计算面积
        {
            return Math.PI * this.R * this.R;
        }
        public override bool IsLegal()                 //判断是否合法，对于圆形、正方形、长方形直接返回true即可
        {
            return true;
        }
    }

    /*定义矩形类*/
    public class Rectangle : Shape
    {
        private double _height;                           //长方形长
        public double Height
        {
            get { return _height; }
            set { _height = value; }
        }
        private double _width;                            //长方形宽
        public double Width
        {
            get { return _width; }
            set { _width = value; }
        }
        public Rectangle(double height, double width)
        {                                                               //构造函数
            Console.Write("创建的图形是：长方形！");
            this.Height = height;
            this.Width = width;
            Console.WriteLine("\t面积是：" + this.GetArea().ToString());
            Shape.sum += this.GetArea();
        }
        public override double GetArea()           //计算面积
        {
            return this.Height * this.Width;
        }
        public override bool IsLegal()                 //判断是否合法
        {
            return true;
        }
    }

    /*定义正方形类*/
    public class Square : Shape
    {
        private double _side;                               //正方形边长
        public double Side
        {
            get { return _side; }
            set { _side = value; }
        }
        public Square(double side)                     //构造函数
        {
            Console.Write("创建的图形是：正方形！");
            this.Side = side;
            Console.WriteLine("\t面积是：" + this.GetArea().ToString());
            Shape.sum += this.GetArea();
        }
        public override double GetArea()           //正方形面积
        {
            return this.Side * this.Side;
        }
        public override bool IsLegal()
        {
            return true;
        }
    }

    /*定义三角形类*/
    public class Triangle : Shape
    {
        private double _side1;                             //定义三角形三边
        public double Side1
        {
            get { return _side1; }
            set { _side1 = value; }
        }
        private double _side2;
        public double Side2
        {
            get { return _side2; }
            set { _side2 = value; }
        }
        private double _side3;
        public double Side3
        {
            get { return _side3; }
            set { _side3 = value; }
        }
        public Triangle(double side1,double side2,double side3)
        {                                                           //构造函数
            Console.Write("创建的图形是：三角形！");
            this.Side1 = side1;
            this.Side2 = side2;
            this.Side3 = side3;
            if (this.IsLegal())
            {
                Console.WriteLine("\t面积是：" + this.GetArea().ToString());
                Shape.sum += this.GetArea();
            }
        }
        public override double GetArea()           //这里利用海伦公式计算了三角形面积
        {
            double p = (this.Side1 + this.Side2 + this.Side3) / 2;
            return Math.Sqrt(p * (p - this.Side1) * (p - this.Side2) * (p - this.Side3));
        }
        /*判断三角形是否合法*/
        public  override bool IsLegal()
        {
            if (this.Side1 >= this.Side2 && this.Side1 >= this.Side3)
                return this.Side2 + this.Side3 > this.Side1;
            if (this.Side2 >= this.Side1 && this.Side2 >= this.Side3)
                return this.Side1 + this.Side3 > this.Side2;
            if (this.Side3 >= this.Side2 && this.Side3 >= this.Side1)
                return this.Side2 + this.Side1 > this.Side3;
            return true;
        }
    }
}
